package com.stylefeng.guns.modular.util;

import java.util.ArrayList;
import java.util.List;

import com.stylefeng.guns.modular.map.model.Point;

/**
 * 地图工具类
 * 
 * @author liqi
 *
 */
public class MapUtil {
	/**
	 * 偏移算法
	 * 
	 * @param value
	 * @param offset
	 * @return
	 */
	public static String offset(String value, String offset) {
		double valueDouble = Double.parseDouble(value);
		double offsetDouble = Double.parseDouble(offset);
		return String.valueOf(valueDouble + offsetDouble);
	}

	/**
	 * 获取两点间的距离
	 * 
	 * @param srcLon
	 * @param srcLat
	 * @param tgtLon
	 * @param tgtLat
	 * @return
	 */
	public static double getDistance(String srcLon, String srcLat, String tgtLon, String tgtLat) {
		if (null == srcLon || "".equals(srcLon) || "NULL".equals(srcLon)) {
			srcLon = "0";
		}
		if (null == srcLat || "".equals(srcLat) || "NULL".equals(srcLat)) {
			srcLat = "0";
		}
		if (null == tgtLon || "".equals(tgtLon) || "NULL".equals(tgtLon)) {
			tgtLon = "0";
		}
		if (null == tgtLat || "".equals(tgtLat) || "NULL".equals(tgtLat)) {
			tgtLat = "0";
		}
		double srcLonDouble = Double.parseDouble(srcLon);
		double srcLatDouble = Double.parseDouble(srcLat);
		double tgtLonDouble = Double.parseDouble(tgtLon);
		double tgtLatDouble = Double.parseDouble(tgtLat);
		double earthPadius = 6378.137;
		double pi = 3.141592625;
		double radSrcLatDouble = srcLatDouble * pi / 180.0;
		double radTgtLatDouble = tgtLatDouble * pi / 180.0;
		double a = radSrcLatDouble - radTgtLatDouble;
		double b = srcLonDouble * pi / 180.0 - tgtLonDouble * pi / 180.0;
		double s = 0;
		s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
				+ Math.cos(radSrcLatDouble) * Math.cos(radTgtLatDouble) * Math.pow(Math.sin(b / 2), 2)));
		s = s * earthPadius * 1000;
		return s;
	}

	/**
	 * 判断点是否在圆内
	 * 
	 * @param lng
	 * @param lat
	 * @param radius
	 * @param pointLng
	 * @param pointLat
	 * @return
	 */
	public static boolean isPointInCircle(String lng, String lat, String radius, String pointLng, String pointLat) {
		double distance = MapUtil.getDistance(lng, lat, pointLng, pointLat);
		if (distance <= Double.parseDouble(radius)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断点是否在多边形内
	 * 
	 * @param lng
	 * @param lat
	 * @param radius
	 * @param pointLng
	 * @param pointLat
	 * @return
	 */
	public static boolean isPointInPolygon(List<Point> points, Point point) {
		int nCross = 0;
		for (int i = 0; i < points.size(); i++) {
			Point p1 = points.get(i);
			Point p2 = points.get((i + 1) % points.size());
			// 取多边形任意一个边,做点point的水平延长线,求解与当前边的交点个数
			// p1p2是水平线段,要么没有交点,要么有无限个交点
			if (p1.getLat() == p2.getLat())
				continue;
			// point 在p1p2 底部 --> 无交点
			if (point.getLat() < Math.min(p1.getLat(), p2.getLat()))
				continue;
			// point 在p1p2 顶部 --> 无交点
			if (point.getLat() >= Math.max(p1.getLat(), p2.getLat()))
				continue;
			// 求解 point点水平线与当前p1p2边的交点的 X 坐标
			double x = (point.getLat() - p1.getLat()) * (p2.getLon() - p1.getLon()) / (p2.getLat() - p1.getLat())
					+ p1.getLon();
			if (x > point.getLon()) // 当x=point.getLon()时,说明point在p1p2线段上
				nCross++; // 只统计单边交点
		}
		// 单边交点为偶数，点在多边形之外 ---
		return (nCross % 2 == 1);
	}

	/**
	 * 将经纬度转换为区域集合
	 * @param lonLat
	 * @return
	 */
	public static List<List<Point>> getPoints(String lonLat) {
		if (lonLat != null && lonLat != "") {
			String[] polygonArr = lonLat.split("&");
			List<List<Point>> polygonList = new ArrayList<>();
			for (int i = 0; i < polygonArr.length; i++) {
				List<Point> pointList = new ArrayList<>();
				String[] pointArr = polygonArr[i].split(";");
				for (int j = 0; j < pointArr.length; j++) {
					String lon = pointArr[j].split(",")[0];
					String lat = pointArr[j].split(",")[1];
					Point point = new Point(Double.parseDouble(lon), Double.parseDouble(lat));
					pointList.add(point);
				}
				polygonList.add(pointList);
			}
			return polygonList;
		}
		return null;
	}
}
